home *** CD-ROM | disk | FTP | other *** search
- /*========================================================================*\
- | File: gui.c Date: 23 Jan 1999 |
- *------------------------------------------------------------------------*
- | Creates windows and requesters, all this stuff that requires |
- | filling in huge structs and arrays. Doesn't do any input processing, |
- | except for some requester-like functions. |
- | |
- \*========================================================================*/
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <proto/gadtools.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/asl.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/wb.h>
- #include <proto/icon.h>
- #include <graphics/gfxbase.h>
- #include <intuition/gadgetclass.h>
-
- #include "gui.h"
-
- /* Simplified version information that controls some of our features. */
- BOOL fGTV39 = FALSE;
- BOOL fIntV39 = FALSE;
- BOOL fGfxV39 = FALSE;
-
- /* Define and nullify the libbases, so libnix doesn't auto-open them. */
- struct GfxBase *GfxBase = NULL;
- struct IntuitionBase *IntuitionBase = NULL;
- struct Library *GadToolsBase = NULL;
- struct Library *AslBase = NULL;
-
-
- enum {
- MSRT_STRING = 0,
- MSRT_LONG,
- MSRT_FLOAT
- };
-
- typedef struct /* Describe one line in a MultiStringRequest(). */
- {
- STRPTR strLabel; /* label in front of this string gadget */
- WORD wType; /* one of the above MSRT_XXX-constants */
- union {
- STRPTR strBuf;
- LONG lVal;
- FLOAT flVal;
- } val;
- WORD wBufSize; /* only needed with MSRT_STRING */
- struct Gadget *pgad; /* for internal purposes */
- } MSR_ITEM;
-
-
- struct Window *pwinMain = NULL;
- struct Menu *menu = NULL;
- struct Screen *scr = NULL;
- APTR visualInfo = NULL;
- struct TextFont *defFont = NULL;
- struct TextAttr defFontA;
- LONG laPens[ 32 ];
-
- /* Propgadgets, must be plain intuition (no gadtools) gadgets. */
- struct Image imgRise, imgSpin;
- struct PropInfo piRise =
- {
- AUTOKNOB | PROPNEWLOOK | FREEVERT,
- MAXPOT, MAXPOT / 2, /* start at 45° */
- MAXBODY, MAXBODY / 10 /* 0 - 90° at 10° granularity */
- };
- struct PropInfo piSpin =
- {
- AUTOKNOB | PROPNEWLOOK | FREEHORIZ,
- MAXPOT / 12 * 5, MAXPOT, /* start at 150° */
- MAXBODY / 13, MAXBODY /* 0 - 360° at 30° granularity */
- };
- struct Gadget gadRise =
- {
- NULL, /* no link */
- 0, 0, 0, 0, /* we'll fill in the dimensions later */
- GFLG_RELHEIGHT | GFLG_RELRIGHT,
- GACT_RELVERIFY | GACT_IMMEDIATE | GACT_RIGHTBORDER,
- GTYP_PROPGADGET,
- &imgRise, NULL, NULL, 0,
- &piRise, IDC_HEIGHT, NULL
- };
- struct Gadget gadSpin =
- {
- NULL,
- 0, 0, 0, 0,
- GFLG_RELWIDTH | GFLG_RELBOTTOM,
- GACT_RELVERIFY | GACT_IMMEDIATE | GACT_BOTTOMBORDER,
- GTYP_PROPGADGET,
- &imgSpin, NULL, NULL, 0,
- &piSpin, IDC_ROTATION, NULL
- };
- /* Oh, and one button gadget. */
- struct Gadget gadCmd =
- {
- NULL,
- 0, 0, 0, 0,
- GFLG_GADGHCOMP | GFLG_RELRIGHT,
- GACT_RELVERIFY | GACT_RIGHTBORDER,
- GTYP_BOOLGADGET,
- /*border*/NULL, NULL, NULL, 0,
- NULL, IDC_STOP_GO, NULL
- };
-
-
- #define AREA_BYTES 100 /* small buffer for simple area fills */
- WORD waArBuf[ AREA_BYTES/2 ];
- struct AreaInfo ari;
- struct TmpRas tras;
- void *ras;
- WORD wMaxX, wMaxY; /* we'll allocate a raster of this size */
-
- #define FNAME_SIZE 40 /* only for the file part of a path name */
-
- /* Shortcut, so the flags don't clutter the layout of the menu table. */
- #define CM CHECKIT | MENUTOGGLE
-
- struct NewMenu nmaMenu[] =
- {
- { NM_TITLE, "Mountain", NULL, 0, 0, NULL },
- { NM_ITEM, "New map", "N", 0, 0, (APTR)IDM_NEW },
- { NM_ITEM, "Border", "B", CM, 0, (APTR)IDM_BORDER },
- { NM_ITEM, "Auto redraw", "A", CM, 0, (APTR)IDM_AUTODRAW },
- { NM_ITEM, "Draw", "D", 0, 0, (APTR)IDM_DRAW },
- { NM_ITEM, "Stop drawing", "X", 0, 0, (APTR)IDM_ABORT },
- { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL },
- { NM_ITEM, "Quit", "Q", 0, 0, (APTR)IDM_QUIT },
-
- { NM_TITLE, "Window", NULL, 0, 0, NULL },
- { NM_ITEM, "Maximize", "M", 0, 0, (APTR)IDM_MAX },
- { NM_ITEM, "Center", "C", 0, 0, (APTR)IDM_CENTER },
- { NM_ITEM, "Zoom", "Z", 0, 0, (APTR)IDM_ZOOM },
-
- { NM_END, NULL, NULL, 0, 0, NULL }
- };
-
- #undef CM
-
-
- /*------------------------------------------------------------------------*\
- This is called upon exit and closes libraries and such stuff.
- Zeroes all its pointers, so it can be safely called more than once.
- \*------------------------------------------------------------------------*/
-
- VOID LibClose( struct Library **ppLib )
- {
- if( *ppLib )
- {
- CloseLibrary( *ppLib );
- *ppLib = NULL;
- }
- }
-
- VOID GetMeOutOfHere()
- {
- LibClose( (struct Library **)&IntuitionBase );
- LibClose( (struct Library **)&GfxBase );
- LibClose( &GadToolsBase );
- LibClose( &AslBase );
- }
-
-
- /*------------------------------------------------------------------------*\
- Allocate all needed system resources and install a cleanup routine
- to close them at exit.
- \*------------------------------------------------------------------------*/
-
- BOOL StartMeUp()
- {
- BOOL fDOSV36;
-
- IntuitionBase = (struct IntuitionBase*)OpenLibrary( "intuition.library", 0 );
- GfxBase = (struct GfxBase*)OpenLibrary( "graphics.library", 0 );
- GadToolsBase = OpenLibrary( "gadtools.library", 0 );
- AslBase = OpenLibrary( "asl.library", 0 );
-
- /* Extract version information. */
- fDOSV36 = (DOSBase && ((struct Library*)DOSBase)->lib_Version >= 36);
- fIntV39 = (IntuitionBase && ((struct Library*)IntuitionBase)->lib_Version >= 39);
- fGfxV39 = (GfxBase && ((struct Library*)GfxBase)->lib_Version >= 39);
- fGTV39 = (GadToolsBase && GadToolsBase->lib_Version >= 39);
-
- /* Some allocations may fail, but others must not, */
- /* and while we can rely on the standard startup code to have opened */
- /* dos.library for us, we must insist that it's V36+. */
- return( fDOSV36 && IntuitionBase && GfxBase && GadToolsBase );
- }
-
-
-
- /*------------------------------------------------------------------------*\
- Set up the window.
- \*------------------------------------------------------------------------*/
-
- BOOL BuildGui()
- {
- WORD wIdx;
- LONG lScrTag;
- struct ColorSpec csa[ 33 ];
-
- if( fGfxV39 )
- { /* use pen sharing with OS 3.x */
- scr = LockPubScreen( NULL );
- if( !scr )
- goto fail;
- lScrTag = WA_PubScreen;
- for( wIdx = 0; wIdx < 16; wIdx++ )
- laPens[ wIdx ] = ObtainBestPen( scr->ViewPort.ColorMap,
- wIdx * 0x10000000,
- wIdx * 0x0A000000,
- wIdx * 0x05000000,
- TAG_DONE ); /* shades of brown */
- laPens[ 16 ] = ObtainBestPen( scr->ViewPort.ColorMap,
- 0x00000000,
- 0x40000000,
- 0x80000000,
- TAG_DONE ); /* blue */
- for( wIdx = 1; wIdx < 16; wIdx++ )
- laPens[ wIdx + 16 ] = ObtainBestPen( scr->ViewPort.ColorMap,
- wIdx * 0x10000000,
- wIdx * 0x10000000,
- wIdx * 0x10000000,
- TAG_DONE ); /* shades of gray */
- }
- else
- { /* else open an own screen */
- for( wIdx = 0; wIdx < 16; wIdx++ )
- {
- csa[ wIdx ].ColorIndex = wIdx;
- csa[ wIdx ].Red = wIdx;
- csa[ wIdx ].Green = (10 * wIdx)/16;
- csa[ wIdx ].Blue = (5 * wIdx)/16;
- } /* shades of brown */
- csa[ 16 ].ColorIndex = 16;
- csa[ 16 ].Red = 0;
- csa[ 16 ].Green = 4;
- csa[ 16 ].Blue = 8; /* blue */
- for( wIdx = 17; wIdx < 32; wIdx++ )
- {
- csa[ wIdx ].ColorIndex = wIdx;
- csa[ wIdx ].Red = wIdx - 16;
- csa[ wIdx ].Green = wIdx - 16;
- csa[ wIdx ].Blue = wIdx - 16;
- } /* shades of gray */
- csa[ 32 ].ColorIndex = -1;
- /* Rearrange some colors, so that we start with gray, black, */
- /* white and blue (which are currently at 24, 0, 31, 16) */
- /* and set up brown, dark gray and light gray (8, 18, 28) for */
- /* the cursor sprite (palette colors 17 through 19). */
- csa[ 24 ].ColorIndex = 0;
- csa[ 0 ].ColorIndex = 1;
- csa[ 31 ].ColorIndex = 2;
- csa[ 16 ].ColorIndex = 3;
- csa[ 8 ].ColorIndex = 17;
- csa[ 28 ].ColorIndex = 19;
- /* Put the palette back in balance. */
- csa[ 1 ].ColorIndex = 8;
- csa[ 2 ].ColorIndex = 16;
- csa[ 3 ].ColorIndex = 24;
- csa[ 17 ].ColorIndex = 28;
- csa[ 19 ].ColorIndex = 31;
- for( wIdx = 0; wIdx < 32; wIdx++ )
- laPens[ wIdx ] = csa[ wIdx ].ColorIndex;
- wIdx = -1;
- scr = OpenScreenTags( NULL,
- SA_Depth, 5,
- SA_DisplayID, LORES_KEY,
- SA_Title, (LONG)"Fractal Mountains",
- SA_Colors, (LONG)&csa,
- SA_Pens, (LONG)&wIdx,
- TAG_DONE );
- if( !scr )
- goto fail;
- lScrTag = WA_CustomScreen;
- }
- wMaxX = scr->Width;
- wMaxY = scr->Height;
-
- if( !(visualInfo = GetVisualInfoA( scr, NULL )) )
- goto fail;
-
- pwinMain = OpenWindowTags( NULL,
- WA_Width, 320,
- WA_Height, 256,
- WA_AutoAdjust, TRUE,
- WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_NEWSIZE
- | IDCMP_RAWKEY | IDCMP_VANILLAKEY
- | IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_INTUITICKS,
- WA_Flags, WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_CLOSEGADGET
- | WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM | WFLG_SIZEBRIGHT
- | WFLG_NEWLOOKMENUS,
- WA_Activate, TRUE,
- WA_ScreenTitle, (LONG)"Fractal Mountains",
- lScrTag, (LONG)scr,
- TAG_DONE );
- if( !pwinMain )
- goto fail;
- WindowLimits( pwinMain, 160, 160, -1L, -1L );
- SetFont( pwinMain->RPort, defFont );
-
- /* Build the menus: */
- menu = CreateMenus( nmaMenu, TAG_DONE );
- if( !menu )
- goto fail;
- LayoutMenus( menu, visualInfo,
- GTMN_NewLookMenus, TRUE,
- TAG_DONE );
- SetMenuStrip( pwinMain, menu );
-
- /* Attach the Gadgets: */
- gadCmd.LeftEdge = -pwinMain->BorderRight + 3;
- gadCmd.TopEdge = pwinMain->BorderTop + 1;
- gadCmd.Width = pwinMain->BorderRight - 4;
- gadCmd.Height = pwinMain->BorderBottom - 2;
- gadRise.LeftEdge = -pwinMain->BorderRight + 3;
- gadRise.TopEdge = pwinMain->BorderTop + pwinMain->BorderBottom;
- gadRise.Width = pwinMain->BorderRight - 4;
- gadRise.Height = -(pwinMain->BorderTop + 2*pwinMain->BorderBottom);
- gadSpin.LeftEdge = 3;
- gadSpin.TopEdge = -pwinMain->BorderBottom + 3;
- gadSpin.Width = -(pwinMain->BorderRight + 3);
- gadSpin.Height = pwinMain->BorderBottom - 4;
- AddGadget( pwinMain, &gadRise, -1 );
- AddGadget( pwinMain, &gadSpin, -1 );
- AddGadget( pwinMain, &gadCmd, -1 );
- RefreshGadgets( &gadRise, pwinMain, NULL );
-
- /* Attach an AreaInfo and a TmpRas to our RastPort, so we can do */
- /* area fill operations on it. */
- ras = AllocRaster( wMaxX, wMaxY );
- if( !ras )
- goto fail;
- InitTmpRas( &tras, ras, RASSIZE( wMaxX, wMaxY ) );
- InitArea( &ari, waArBuf, AREA_BYTES/5 );
- pwinMain->RPort->TmpRas = &tras;
- pwinMain->RPort->AreaInfo = &ari;
-
- return TRUE;
-
- fail:
- DestroyGui();
- return FALSE;
- }
-
-
-
- /*------------------------------------------------------------------------*\
- Tear down the window and close (or release) the screen it's on.
- Closes the child window first, which shares some of our resources
- (screen and menus).
- \*------------------------------------------------------------------------*/
-
- VOID DestroyGui()
- {
- WORD wColor;
-
- if( pwinMain )
- {
- ClearMenuStrip( pwinMain );
- CloseWindow( pwinMain );
- }
- pwinMain = NULL;
- if( ras )
- FreeRaster( ras, wMaxX, wMaxY );
- if( menu )
- FreeMenus( menu );
- menu = NULL;
- if( visualInfo )
- FreeVisualInfo( visualInfo );
- visualInfo = NULL;
- if( scr )
- if( fGfxV39 )
- {
- UnlockPubScreen( NULL, scr );
- for( wColor = 0; wColor < 32; wColor++ )
- ReleasePen( scr->ViewPort.ColorMap, laPens[ wColor ] );
- }
- else
- CloseScreen( scr );
- scr = NULL;
- }
-
-
-
- /*------------------------------------------------------------------------*\
- Disable input to the main window by putting up an invisible requester,
- as shown in the RKRM example. Supply FALSE to enable input again.
- If we have OS3.x, we will also set a busy pointer for the main window
- while it is locked.
- \*------------------------------------------------------------------------*/
-
- VOID DisableMainWindow( BOOL fReally )
- {
- static struct Requester rq;
- static BOOL fLocked = FALSE;
-
- if( fReally && !fLocked )
- {
- InitRequester( &rq );
- fLocked = Request( &rq, pwinMain );
- if( fLocked & fIntV39 )
- SetWindowPointer( pwinMain,
- WA_BusyPointer, TRUE,
- TAG_DONE );
- }
-
- if( !fReally && fLocked )
- {
- fLocked = FALSE;
- EndRequest( &rq, pwinMain );
- if( fIntV39 )
- SetWindowPointer( pwinMain, TAG_DONE );
- }
- }
-
-
-
- /*------------------------------------------------------------------------*\
- Set up or clear a busy pointer for the main window.
- Only works with OS3.x.
- Use this instead of DisableMainWindow(), if you are still going to check
- the window's message port during whatever you're doing.
- \*------------------------------------------------------------------------*/
-
- VOID SnoozeMainWindow( BOOL fReally )
- {
- if( fIntV39 )
- SetWindowPointer( pwinMain,
- !fReally ? TAG_DONE :
- WA_BusyPointer, TRUE,
- /*WA_PointerDelay, TRUE,*/
- TAG_DONE );
- }
-
-
-
- /*------------------------------------------------------------------------*\
- Open a window with some string gadgets and labels in it,
- as described by the supplied MSR_ITEMs.
- The window's initial position is specified by the IBox parameter, and
- its final position is returned there, too. Note that the *height* of the
- window is always calculated automatically.
- The supplied screen must not be NULL.
- In case the "requester" is cancelled, the supplied buffers will remain
- unchanged and the return value is FALSE.
- Note: This subroutine uses no global variables, so it might be useful
- in other projects, too.
- \*------------------------------------------------------------------------*/
-
- VOID GadgetOnOff( struct Window *pwin, struct Gadget *pgad )
- /* Put in a separate function to work around a silly "spilled */
- /* register" error from GCC. */
- {
- GT_SetGadgetAttrs( pgad, pwin, NULL,
- GA_Disabled, TRUE,
- TAG_DONE );
- GT_SetGadgetAttrs( pgad, pwin, NULL,
- GA_Disabled, FALSE,
- TAG_DONE );
- }
-
- BOOL MultiStringRequest( struct Screen *pscr, BOOL fPubScreen, struct IBox *pib,
- STRPTR strHail, STRPTR strOk, STRPTR strCancel,
- WORD wItems, MSR_ITEM *pmi )
- {
- struct Window *pwin = NULL;
- struct NewGadget ng;
- struct Gadget *pgad, *pgadRoot = NULL;
- struct Gadget *pgadFirst = NULL, *pgadLast;
- struct IntuiMessage *intuiMsg;
- struct VisualInfo *pvi;
- char caBuf[ 20 ];
- WORD wFontY = pscr->Font->ta_YSize;
- WORD wStrGadH = wFontY + 8, wButtonH = wFontY + 4;
- WORD wStrSepH = wFontY / 2, wButSepH = wFontY;
- WORD wTopH = wFontY / 2, wBottomH = wFontY / 2;
- WORD wBorderW = wFontY / 2, wLabSepW = wFontY / 2;
- WORD wButtonW, wLabelW, wTemp, wIdx;
- STRPTR str;
- BOOL fQuit = FALSE, fResult = FALSE;
- enum { IDC_STATIC, IDC_OK, IDC_CANCEL, IDC_INPUT };
-
- assert( pscr != NULL );
- if( !(pvi = GetVisualInfoA( pscr, NULL )) )
- return FALSE;
- pwin = OpenWindowTags( NULL,
- WA_Left, pib->Left,
- WA_Top, pib->Top,
- WA_Width, pib->Width,
- WA_InnerHeight, wTopH + wItems*(wStrGadH + wStrSepH) - wStrSepH
- + wButSepH + wButtonH + wBottomH,
- WA_AutoAdjust, TRUE,
- WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY | IDCMP_VANILLAKEY
- | STRINGIDCMP,
- WA_Flags, WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_CLOSEGADGET,
- WA_Activate, TRUE,
- WA_Title, (LONG)strHail,
- !fPubScreen ? WA_CustomScreen :
- WA_PubScreen, (LONG)pscr,
- TAG_DONE );
- if( pwin == NULL )
- goto fail;
-
- /* Determine the width of the buttons and the labels. */
- str = strCancel;
- wButtonW = TextLength( pwin->RPort, str, strlen( str ) );
- str = strOk;
- wTemp = TextLength( pwin->RPort, str, strlen( str ) );
- if( wButtonW < wTemp )
- wButtonW = wTemp;
- wButtonW = 3 * wButtonW / 2;
- wLabelW = 0;
- for( wIdx = 0; wIdx < wItems; wIdx++ )
- {
- str = pmi[ wIdx ].strLabel;
- if( str != NULL )
- {
- wTemp = TextLength( pwin->RPort, str, strlen( str ) );
- if( wLabelW < wTemp )
- wLabelW = wTemp;
- }
- }
- if( wLabelW != 0 )
- wLabelW += wLabSepW;
-
- /* Add some gadtools gadgets. */
- pgad = CreateContext( &pgadRoot );
-
- /* string gadgets */
- ng.ng_VisualInfo = pvi;
- ng.ng_TextAttr = pscr->Font;
- ng.ng_Flags = 0;
- ng.ng_LeftEdge = pwin->BorderLeft + wBorderW + wLabelW;
- ng.ng_Width = pwin->Width - pwin->BorderRight - wBorderW - ng.ng_LeftEdge;
- ng.ng_TopEdge = pwin->BorderTop + wTopH;
- ng.ng_Height = wStrGadH;
- ng.ng_GadgetText = NULL;
- for( wIdx = 0; wIdx < wItems; wIdx++ )
- {
- ng.ng_GadgetID = IDC_INPUT + wIdx;
- switch( pmi[ wIdx ].wType )
- {
- case MSRT_STRING:
- pgad = CreateGadget( STRING_KIND, pgad, &ng,
- GTST_String, (LONG)pmi[ wIdx ].val.strBuf,
- GTST_MaxChars, pmi[ wIdx ].wBufSize,
- TAG_DONE );
- break;
- case MSRT_LONG:
- pgad = CreateGadget( INTEGER_KIND, pgad, &ng,
- GTIN_Number, pmi[ wIdx ].val.lVal,
- TAG_DONE );
- break;
- case MSRT_FLOAT:
- sprintf( caBuf, "%g", pmi[ wIdx ].val.flVal );
- pgad = CreateGadget( STRING_KIND, pgad, &ng,
- GTST_String, (LONG)caBuf,
- GTST_MaxChars, sizeof( caBuf ),
- TAG_DONE );
- break;
- default: /* invalid entry type */
- assert( FALSE );
- }
- pmi[ wIdx ].pgad = pgad;
- ng.ng_TopEdge += wStrGadH + wStrSepH;
- if( pgadFirst == NULL )
- pgadFirst = pgad;
- }
- pgadLast = pgad;
-
- /* OK and Cancel buttons */
- ng.ng_Width = wButtonW;
- ng.ng_TopEdge += wButSepH - wStrSepH;
- ng.ng_Height = wButtonH;
- ng.ng_GadgetText = strOk;
- ng.ng_GadgetID = IDC_OK;
- pgad = CreateGadget( BUTTON_KIND, pgad, &ng, TAG_DONE );
-
- ng.ng_LeftEdge = pwin->Width - pwin->BorderRight - wBorderW - wButtonW;
- ng.ng_GadgetText = strCancel;
- ng.ng_GadgetID = IDC_CANCEL;
- pgad = CreateGadget( BUTTON_KIND, pgad, &ng, TAG_DONE );
-
- if( pgad == NULL )
- goto fail;
-
- AddGList( pwin, pgadRoot, -1, -1, NULL );
- RefreshGList( pgadRoot, pwin, NULL, -1 );
- GT_RefreshWindow( pwin, NULL );
-
- ActivateGadget( pgadFirst, pwin, NULL );
- while( !fQuit )
- {
- intuiMsg = GT_GetIMsg( pwin->UserPort );
- if( !intuiMsg )
- {
- WaitPort( pwin->UserPort );
- continue;
- }
- switch( intuiMsg->Class )
- {
- case IDCMP_GADGETUP:
- pgad = intuiMsg->IAddress;
- if( pgad == pgadLast ) /* msg from the last string gadget */
- {
- /* Hitting enter in the last string gadget implies */
- /* closing the requester. Shift-Enter however should */
- /* enable the user to simply deactivate any string */
- /* gadgets (so he can type shortcuts to other gadgets, */
- /* maybe ESC in particular). */
- if( (intuiMsg->Qualifier
- & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0 )
- break;
- else if( intuiMsg->Code == 0 )
- {
- fResult = TRUE;
- fQuit = TRUE;
- }
- else if( intuiMsg->Code == 9 )
- {
- /* We don't want TAB to cycle from the last to */
- /* the first of our string gadgets. */
- /* To prevent this, we simply deactivate the */
- /* first string gadget, and the only legal way to */
- /* do this for a gadtools gadget is by disabling */
- /* and reenabling it. */
- GadgetOnOff( pwin, pgadFirst );
- }
- else
- /* On systems with MCP or such installed, we */
- /* will get here in reply to ESC. */
- fQuit = TRUE;
- }
- else switch( pgad->GadgetID )
- {
- case IDC_OK:
- fResult = TRUE;
- fQuit = TRUE;
- break;
- case IDC_CANCEL:
- fQuit = TRUE;
- break;
- }
- break;
- case IDCMP_VANILLAKEY:
- switch( intuiMsg->Code )
- {
- case 9: /* TAB reenables the string gadget gang. */
- ActivateGadget( pgadFirst, pwin, NULL );
- break;
- case 13:
- fResult = TRUE;
- fQuit = TRUE;
- break;
- case 27:
- fQuit = TRUE;
- break;
- }
- break;
- case IDCMP_CLOSEWINDOW:
- fQuit = TRUE;
- break;
- }
- GT_ReplyIMsg( intuiMsg );
- }
- if( fResult )
- /* Copy the contents of the string gadgets. */
- for( wIdx = 0; wIdx < wItems; wIdx++ )
- {
- str = ((struct StringInfo *)pmi[ wIdx ].pgad->SpecialInfo)->Buffer;
- switch( pmi[ wIdx ].wType )
- {
- case MSRT_STRING:
- strcpy( pmi[ wIdx ].val.strBuf, str );
- break;
- case MSRT_LONG:
- pmi[ wIdx ].val.lVal = atol( str );
- break;
- case MSRT_FLOAT:
- pmi[ wIdx ].val.flVal = atof( str );
- break;
- }
- }
-
- pib->Left = pwin->LeftEdge; /* Remember window position */
- pib->Top = pwin->TopEdge;
- pib->Width = pwin->Width;
- pib->Height = pwin->Height;
- fail:
- if( pwin )
- CloseWindow( pwin );
- if( pgadRoot )
- FreeGadgets( pgadRoot );
- if( pvi )
- FreeVisualInfo( pvi );
-
- return fResult;
- }
-
-
-
- /*------------------------------------------------------------------------*\
- Open a window with a string gadget in it and read a string.
- In case the "requester" is cancelled, the supplied buffer will remain
- unchanged.
- \*------------------------------------------------------------------------*/
-
- BOOL StringRequest( STRPTR strHail, STRPTR strBuf, WORD wSize )
- {
- struct IBox ib;
- MSR_ITEM mi;
- BOOL fResult;
-
- mi.strLabel = NULL;
- mi.wType = MSRT_STRING;
- mi.val.strBuf = strBuf;
- mi.wBufSize = wSize;
-
- /* open relative to main window */
- ib.Left = pwinMain->LeftEdge + 50;
- ib.Top = pwinMain->TopEdge + 50;
- ib.Width = pwinMain->Width - 100;
-
- DisableMainWindow( TRUE );
- fResult = MultiStringRequest( scr, fGfxV39, &ib, strHail,
- "OK", "Cancel", 1, &mi );
- DisableMainWindow( FALSE );
- return fResult;
- }
-
-